package org.amse.Archiver.algorithm;

import org.amse.Archiver.algorithm.huffman.*;

public class CodeBuilder {
    private static final int LENGTH_ARRAY = 256;
    private final int myTreeSize;
	private final int myColLeaves;
    private int[] visited;
	private byte[][] myCodeArray;
	private byte[] myHelpArray;
	
    public CodeBuilder(ITree tree) {
        myTreeSize = tree.getTreeSize();
        myColLeaves = tree.getNum();
		visited = new int[myTreeSize + 1];
        myCodeArray = new byte[LENGTH_ARRAY][LENGTH_ARRAY];

        for (int i = 0; i < LENGTH_ARRAY; i++) {
			myCodeArray[i][0] = -1;
		}
		myHelpArray = new byte[LENGTH_ARRAY];
		Node root = tree.getRoot();
	    byte rootVal = -1;
		dfs(root, 0, rootVal);
    }
		
	private void dfs(Node v, int index, byte value) {
		visited[v.getIndex()] = 1; 
		myHelpArray[index] = value;
		byte leftVal = 1;
		byte rightVal = 0;
		byte endVal = -1;
		if(v.getLeft() == null && v.getRight() == null) {
		    myHelpArray[index+1] = endVal;
			for (int i = 0; i <= index+1; i++) {
                myCodeArray[v.getCodeSym()][i] = myHelpArray[i+1];
            }
			index = 0;
		}
		
		if (v.getLeft() != null && visited[(v.getLeft()).getIndex()] != 1) {
			dfs(v.getLeft(), index + 1, leftVal);
		}
		
		if (v.getRight() != null && visited[(v.getRight()).getIndex()] != 1) {
			dfs(v.getRight(), index + 1, rightVal);
		}
	}
	
	public final byte[][] getCode() {
	    return myCodeArray;
	}
	
	public String toString() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < LENGTH_ARRAY; i++) {
			sb.append(i + " - ");
			int j = 0;
			while(j != myColLeaves - 2 && myCodeArray[i][j] != -1) {
				sb.append(myCodeArray[i][j] + "; \n");
				j++;
			}
		
		}
		return sb.toString();
	}
}